//
// Book:      OpenGL(R) ES 2.0 Programming Guide
// Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
// ISBN-10:   0321502795
// ISBN-13:   9780321502797
// Publisher: Addison-Wesley Professional
// URLs:      http://safari.informit.com/9780321563835
//            http://www.opengles-book.com
//

// Hello_Triangle
//
//    This is a simple example that draws a single triangle with
//    a minimal vertex/fragment shader.  The purpose of this
//    example is to demonstrate the basic concepts of
//    OpenGL ES 2.0 rendering.

package com.example.open_gl_es_examples;


import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.util.Log;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

/**
 * Slightly modified
 */
public class HelloTrialngleRenderer implements GLSurfaceView.Renderer {

    private static final String TAG = HelloTrialngleRenderer.class.getSimpleName();

    private int mProgramObject;
    private int mWidth;
    private int mHeight;
    private FloatBuffer mVertices;

    private final float[] mVerticesData = {
             0.0f,  0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
             0.5f, -0.5f, 0.0f
    };


    public HelloTrialngleRenderer(Context context) {
        mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4)
                .order(ByteOrder.nativeOrder()).asFloatBuffer();
        mVertices.put(mVerticesData).position(0);
    }

    /*
     * Create a shader object, load the shader source and compile the shader
     */
    private int loadShader(int type, String shaderSrc) {
        int shader;
        int compiled[] = new int[1];

        shader = GLES20.glCreateShader(type);

        if (shader == 0) {
            return 0;
        }

        GLES20.glShaderSource(shader, shaderSrc); // Load the shader source
        GLES20.glCompileShader(shader); // Compile the shader
        GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);

        if (compiled[0] == 0) {
            Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
            GLES20.glDeleteShader(shader);
            return 0;
        }
        return shader;
    }

    /*
     * Initialize the shader and program object
     */
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        String vShaderStr =
                "attribute vec4 vPosition;      \n" +
                "void main()                    \n" +
                "{                              \n" +
                "   gl_Position = vPosition;    \n" +
                "}                              \n";

        String fShaderStr =
                "precision mediump float;        \n" +
                "void main()                    \n" +
                "{                              \n" +
                "   gl_FragColor = vec4 (1.0, 0.0, 0.0, 1.0);\n" +
                "}                              \n";

        int vertexShader;
        int fragmentShader;
        int programObject;
        int[] linked = new int[1];

        // Load the vertex/fragment shaders
        vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vShaderStr);
        fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fShaderStr);

        // create the program object
        programObject = GLES20.glCreateProgram();

        if (programObject == 0) {
            return;
        }

        GLES20.glAttachShader(programObject, vertexShader);
        GLES20.glAttachShader(programObject, fragmentShader);

        // Bind vPosition to attribute 0
        GLES20.glBindAttribLocation(programObject, 0, "vPosition");

        // Link the program
        GLES20.glLinkProgram(programObject);

        // Check the link status
        GLES20.glGetProgramiv(programObject, GLES20.GL_LINK_STATUS, linked, 0);

        if (linked[0] == 0) {
            Log.e(TAG, "Error linking program:");
            Log.e(TAG, GLES20.glGetProgramInfoLog(programObject));
            GLES20.glDeleteProgram(programObject);
            return;
        }

        // Store the program object
        mProgramObject = programObject;

        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        mWidth = width;
        mHeight = height;
    }

    /*
     * Draw a triangle using the shader pair created in onSurfaceCreated()
     */
    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glViewport(0, 0, mWidth, mHeight); // Set the viewport
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); // Clear the color buffer
        GLES20.glUseProgram(mProgramObject);

        // Load the vertex data
        GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, mVertices);
        GLES20.glEnableVertexAttribArray(0);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
    }
}
